<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { NCard, NSpace, NButton } from 'naive-ui'

import { useUserStore } from '@/stores/userStore'

import { Terminal } from 'xterm'
import { FitAddon } from 'xterm-addon-fit'
import "xterm/css/xterm.css"

type SshMessage = {
    account: string
    serverName: string
    commandType: string
    command: string
}

const userStore = useUserStore()
const router = useRouter()
const route = useRoute()

const serverName = ref<string>("")
const connectionStatus = ref<string>("连接中...")
// onMunted后，会与此绑到一起<div ref="websshContainer" />
const websshContainer = ref()
let terminal: Terminal
let websocket: WebSocket
let fitAddon: FitAddon

onMounted(() => {
    serverName.value = route.query.serverName as string
    initWebsocket()
})
onUnmounted(() => {
    close()
})

function close() {
    const request: SshMessage = {
        account: userStore.account,
        serverName: serverName.value,
        commandType: "CLOSE",
        command: ''
    }
    websocket.send(JSON.stringify(request))
    websocket.close()
    window.removeEventListener("resize", terminalResize)
}

function initWebsocket() {
    websocket = new WebSocket("ws://127.0.0.1:8080/server")
    websocket.onopen = function (event) {
        connectionStatus.value = "连接成功"
        initSsh()
        initTerminal()
        window.addEventListener("resize", terminalResize)
    }
    websocket.onmessage = function (event) {
        terminal.write(event.data)
    }
    websocket.onerror = function (event) {
        connectionStatus.value = "连接异常"
    }
    websocket.onclose = function (event) {
        connectionStatus.value = "连接关闭"
    }
}

function initSsh() {
    const request: SshMessage = {
        account: userStore.account,
        serverName: serverName.value,
        commandType: "CONNECT",
        command: ''
    }
    websocket.send(JSON.stringify(request))
}

function initTerminal() {
    fitAddon = new FitAddon()
    terminal = new Terminal({
        lineHeight: 1.2,
        fontSize: 12,
        fontFamily: "Monaco, Menlo, Consolas, 'Courier New', monospace",
        theme: {
            background: '#001529',
        },
        // 光标闪烁
        cursorBlink: true,
        cursorStyle: 'bar'
    })
    terminal.loadAddon(fitAddon)
    terminal.open(websshContainer.value)
    fitAddon.fit()
    terminal.onData((str) => {
        const request: SshMessage = {
            account: userStore.account,
            serverName: serverName.value,
            commandType: "SHELL",
            command: str
        }
        websocket.send(JSON.stringify(request))
    })
}

function terminalResize() {
    fitAddon.fit()
}
</script>

<template>
    <div class="flame-container">
        <n-card :content-style="{ display: 'flex' }" :bordered="false">
            <template #header>
                <n-space justify="space-between">
                    <div>
                        <n-space>
                            <div>
                                服务器名称：{{ serverName }}
                            </div>
                            <div>
                                WebSocket{{ connectionStatus }}
                            </div>
                        </n-space>
                    </div>
                    <div>
                        <n-button quaternary @click="router.back()">返回</n-button>
                    </div>
                </n-space>
            </template>
            <div ref="websshContainer" class="websshContainer">

            </div>
        </n-card>
    </div>
</template>

<style scoped>
.websshContainer {
    flex: 1;
}
</style>